#include "structure/Cabin.h"
#include "Constants.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform2.hpp>
#include <glm/gtx/projection.hpp>
#include <math.h>
#include "InputMgr.h"
#include "TextureMgr.h"

const char Cabin::cabinLeft = KEY_CABIN_ROTATE_LEFT;
const char Cabin::cabinRight = KEY_CABIN_ROTATE_RIGTH;


Cabin::Cabin(GLuint programHandler, GLShaderConfig shaderConfig, float widthX, float widthY, float height) :
	GLStructure(programHandler, shaderConfig),
	widthX(widthX),
	widthY(widthY),
	height(height),
	cabinRotationAngle(0) {
	cabin = new Cube(programHandler, shaderConfig);
	counterweight = new Cube(programHandler, shaderConfig);
	boom = new Boom(programHandler, shaderConfig, height * 50 / 100, height * 30 / 100, BOOM_LENGTH);

	components.push_back(cabin);
	components.push_back(counterweight);
	structures.push_back(boom);

	cabin->setTextureData(TextureMgr::getInstance()->getCabinDiffuseTextureData(), TextureMgr::getInstance()->getCabinDirtTextureData());

	counterweight->setColor(0.6, 0.6, 0.6);
	counterweight->setTextureData(NULL, TextureMgr::getInstance()->getCabinDirtTextureData());

	InputMgr::getInstance()->registerListener(this);
}

Cabin::~Cabin() {
	components.clear();
	structures.clear();

	delete cabin;
	delete counterweight;
	delete boom;
}

void Cabin::updateComponents() {
	glm::mat4 cabinRotation = glm::rotate(transformationMatrix, cabinRotationAngle, glm::vec3(0, 0, 1));

	glm::mat4 transformation = glm::translate(cabinRotation, glm::vec3(0, 0, height/2));
	transformation = glm::scale(transformation, glm::vec3(widthX, widthY, height));
	cabin->transform(transformation);

	transformation = glm::translate(cabinRotation, glm::vec3(-widthX/2, 0, height));
	transformation = glm::scale(transformation, glm::vec3(widthX/3, widthY*6/5, height/4));
	counterweight->transform(transformation);


	transformation = glm::translate(cabinRotation, glm::vec3(widthX / 4, 0, height/2));
	transformation = glm::rotate(transformation, -90.0f, glm::vec3(0.0, 0.0, 1.0));
	boom->transform(transformation);
}

void Cabin::update (glm::mat4 viewMatrix, glm::mat4 modelMatrix) {
	updateComponents();
//	TextureMgr::getInstance()->initTexture(TextureMgr::diffuseTexture, this->programHandler); //TODO No hacer esto en cada update para cada cubo!!!
	TextureMgr::getInstance()->loadTextures(programHandler);
	cabin->update(viewMatrix, modelMatrix);
	counterweight->update(viewMatrix, modelMatrix);
	boom->update(viewMatrix, modelMatrix);
}

void Cabin::OnKeyDown(int nKey, char cAscii) {
	if (cAscii == cabinLeft) {
		cabinRotationAngle += CABIN_SPEED;
		if (cabinRotationAngle > 360.0f) {
			cabinRotationAngle -= 360.0f;
		}
	} else if (cAscii == cabinRight) {
		cabinRotationAngle -= CABIN_SPEED;
		if (cabinRotationAngle < 0) {
			cabinRotationAngle += 360.0f;
		}
	}
}
